#include "rational.h"

dRational::dRational ()
{
  numerator = 0;
  denominator = 1;
}

dRational::dRational (string x)
{
  int slash = x.find ('/');
  cout << "slash: " << slash << endl;
  dRational (x.substr (0, slash), x.substr (slash+1));
}

dRational::dRational (const char *x)
{
  
}

dRational::dRational (double n)
{
  numerator = n;
  denominator = 1;
}

dRational::dRational (int n, int d)
{
  numerator = n;
  denominator = d;
}

dRational::dRational (const char *n, const char *d)
{
  char * endPointer;
  printf ("n: %s\nd: %s\n", n, d);
  numerator = (int)strtol (n, &endPointer, 10);
  denominator = (int)strtol (d, &endPointer, 10);
  if (errno == EINVAL)
    denominator = 1;
}

dRational::dRational (string n, string d)
{
  dRational (n.c_str (), d.c_str ());
}

dRational::~dRational ()
{
}

dRational
dRational::operator+ (const dRational &x)
{
  dRational result;
  if (denominator > x.denominator)
    result = dRational (numerator+x.numerator*denominator, denominator);
  else if (denominator < x.denominator)
    result = dRational (x.numerator+numerator*x.denominator, x.denominator);
  else
    result = dRational (numerator+x.numerator, denominator);
  result.reduce ();
  return result;
}

dRational
dRational::operator- (const dRational &x)
{
  dRational result;
  if (denominator > x.denominator)
    result = dRational (numerator*x.denominator
			- x.numerator*denominator,
			denominator*x.denominator);
  else if (denominator < x.denominator)
    result = dRational (x.numerator-numerator*x.denominator, x.denominator);
  else
    result = dRational (numerator-x.numerator, denominator);
  result.reduce ();
  return result;
}

dRational
dRational::operator* (const dRational &x)
{
  dRational result = dRational (numerator*x.numerator,
				denominator*x.denominator);
  result.reduce ();
  return result;
}

dRational
dRational::operator/ (const dRational &x)
{
  dRational result;
  if (denominator > x.denominator)
    result = dRational (numerator/x.numerator*denominator, denominator);
  else if (denominator < x.denominator)
    result = dRational (x.numerator/numerator*x.denominator, x.denominator);
  else
    result = dRational (numerator/x.numerator, denominator);
  result.reduce ();
  return result;
}

void
dRational::reduce ()
{
  if (numerator % denominator == 0)
    {
      numerator /= denominator;
      denominator = 1;
    }
  else if (denominator % numerator == 0)
    {
      denominator /= numerator;
      numerator = 1;
    }
  else
    {
      int i;
      if (numerator > denominator)
	i = denominator/4;
      else
	i = numerator/4;
      for (++i; i > 1; i--)
	{
	  if (numerator % i == 0 && denominator % i == 0)
	    {
	      numerator /= i;
	      denominator /= i;
	    }
	}
    }
}

char *
dRational::c_str ()
{
  char *buffer = new char[256];
  sprintf (buffer, "%i/%i", numerator, denominator);
  return buffer;
}

string
dRational::toString ()
{
  return string (c_str ());
}
